package com.mycompany.app.common.audit.modification.hibernate.interceptor;

import java.io.Serializable;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

import com.mycompany.app.common.audit.AuditBaseObject;
import com.mycompany.app.common.security.acegi.SecurityUtils;

/**
 * Set audit fields for Object implements IAuditable Interface.
 * @author Shawn.guo
 *
 */
@SuppressWarnings("serial")
public class AuditInterceptor extends EmptyInterceptor {

    protected enum Audit_Field {
        lastModifiedBy, createBy, createDate, lastModifiedDate
    };
    
    protected final Log logger = LogFactory.getLog(getClass());

    public boolean onSave(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) {
        boolean modified = false;

        logger.debug("In AuditInterceptor.onSave    "+entity.getClass());
        if (entity instanceof AuditBaseObject) {
            for (int i = 0; i < propertyNames.length; i++) {
                if (propertyNames[i].equals(Audit_Field.createDate.name())) {
                    state[i] = new Date();
                    modified = true;
                }
                if (propertyNames[i].equals(Audit_Field.createBy.name())) {
                    state[i] = SecurityUtils.getCurrentLoginName();
                    modified = true;
                }
            }
        }
        return modified;
    }

    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) {
        boolean modified = false;
        
        logger.debug("In AuditInterceptor.onFlushDirty    "+entity.getClass());
        if (entity instanceof AuditBaseObject) {
            for (int i = 0; i < propertyNames.length; i++) {
                if (propertyNames[i]
                        .equals(Audit_Field.lastModifiedDate.name())) {
                    currentState[i] = new Date();
                    modified = true;
                }
                if (propertyNames[i].equals(Audit_Field.lastModifiedBy.name())) {
                    currentState[i] = SecurityUtils.getCurrentLoginName();
                    modified = true;
                }
            }
        }
        return modified;

    }
}
